#include<iostream>
#include<string>
#include<cstring>
#include <unistd.h>
#include<functional>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include"Terminal.hpp" 
using namespace std;

//./UdpClient serverip serverport
void Usage(string proc)
{
    cout<<"\n\tUsage : "<<proc<<" ServerIp ServerPort"<<endl;
}

struct ThreadData
{
    struct sockaddr_in server;
    string serverip;
    int sockfd;
};

void* recv_message(void* args)
{
    //OpenTerminal();   //使发消息和收消息的窗口分开
    char buffer[1024];
    ThreadData* td=static_cast<ThreadData*>(args);
    struct sockaddr_in server=td->server;
    string serverip=td->serverip;
    int sockfd=td->sockfd;
    while(true)
    {
        unsigned int len=sizeof(server);
        int n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&server, &len);
        if (n > 0)
        {
            buffer[n] = '\0';
            cerr << buffer << endl;  //用的是cerr，因为send_message部分有cout输出
        }
    }
    return nullptr;
}

void* send_message(void* args)
{
    string message;
    ThreadData* td=static_cast<ThreadData*>(args);
    struct sockaddr_in server=td->server;
    string serverip=td->serverip;
    int sockfd=td->sockfd;
    while(true)
    {
        cout<<"Please Enter@";
        getline(cin,message);
        int n=sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&server, sizeof(server));
    }
    return nullptr;
}

int main(int argc,char* argv[])
{
    if(argc<3)
    {
        Usage(argv[0]);
        exit(1);
    }

    //完善server的地址结构体
    string serverip=argv[1];
    uint16_t serverport=stoi(argv[2]);    //stoi:将字符串转化为整数

    struct sockaddr_in server;
    bzero(&server, sizeof(server));  //相当于memset  
    server.sin_addr.s_addr=inet_addr(serverip.c_str()); //将 IPv4 点分十进制字符串（如 "192.168.1.1"）转换为 32 位网络字节序的整数值。
    server.sin_family=AF_INET;
    server.sin_port=htons(serverport);

    //创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);  //UDP,打开了网卡文件
    if(sockfd<0)
    {
        cout<<"socket create error"<<endl;
        exit(1);
    }

    struct ThreadData td;
    td.server=server;
    td.serverip=serverip;
    td.sockfd=sockfd;

    pthread_t thread1,thread2;
    pthread_create(&thread1, nullptr, recv_message,(void*)&td);
    pthread_create(&thread2, nullptr, send_message, (void*)&td);
            
    // string message;
    // char buffer[1024];  //收信息使用
    // while(true)
    // {
    //     //发信息
    //     cout<<"Please Enter@";
    //     getline(cin,message);
    //     int n=sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&server, sizeof(server));

    //     //收信息
    //     unsigned int len=sizeof(server);
    //     n=recvfrom(sockfd, buffer, sizeof(buffer)-1, 0, (struct sockaddr *)&server, &len);
    //     if(n>0)
    //     {
    //         buffer[n]='\0';
    //         cout<<buffer<<endl;
    //     }
    // }

    pthread_join(thread1, nullptr);
    pthread_join(thread2, nullptr);

    close(sockfd);
    return 0;
}

